#include <stdio.h>  //预处理指令器
#include <float.h>
#include <stdlib.h>

#define LENGTH 10
#define WIDTH 5
#define NEWLINE '\n'

int main(void) //主函数-程序的开始
{
    /*我是多行
    注释*/
    //我是单行注释
    printf("int 存储大小 : %lu \n", sizeof(int));
    printf("float 存储最大字节数 : %lu \n", sizeof(float));
    printf("float 最小值: %E\n", FLT_MIN);
    printf("float 最大值: %E\n", FLT_MAX);
    printf("精度值: %d\n", FLT_DIG);

    //题目：有1、2、3、4个数字，能组成多少个互不相同且无重复数字的三位数？都是多少？
    int i, j, k, count = 0,a,b=0;

    for (i = 1; i <= 4; i++)
        for (j = 1; j <= 4; j++)
            for (k = 1; k <= 4; k++)
            {
                if (i != j && i != k && k != j)
                {
                    count++;
                    printf("%d%d%d\n", i, j, k);
                }
            }
    printf("共有%d个\n", count); //输出函数调用与预处理的stdio

    //递加1到100
    for(a=1;a<=100;a++)
    {
        b += a;
    }
    printf("%d",b);

    //利用算法算递加
    int aa=1,bb=100,cc;

    cc = bb*(aa+bb)/2;
    printf("\n%d\n",cc);

    //转义字符
    printf("Hello\tWorld\n\n");
    printf("\a\b\f\t\0137");

    //预处理器
    int area;

    area = LENGTH * WIDTH;
    printf("value of area : %d", area);
    printf("%c", NEWLINE);

    //关键字
    const int DXINT = 10;

    printf("%d\n",DXINT);

    //运算符
    int a_1 = 21;
    int b_1 = 10;
    int c_1;

    c_1 = a_1 + b_1;
    printf("Line 1 - c 的值是 %d\n", c_1);
    c_1 = a_1 - b_1;
    printf("Line 2 - c 的值是 %d\n", c_1);
    c_1 = a_1 * b_1;
    printf("Line 3 - c 的值是 %d\n", c_1);
    c_1 = a_1 / b_1;
    printf("Line 4 - c 的值是 %d\n", c_1);
    c_1 = a_1 % b_1;
    printf("Line 5 - c 的值是 %d\n", c_1);
    c_1 = a_1++; // 赋值后再加 1 ，c 为 21，a 为 22
    printf("Line 6 - c 的值是 %d\n", c_1);
    c_1 = a_1--; // 赋值后再减 1 ，c 为 22 ，a 为 21
    printf("Line 7 - c 的值是 %d\n", c_1);
    
    return 0; //结束main函数  并返回0
}

// c语言基本语法
/*
    C语言组成 关键字、标识符、常量、字符串值，或者是一个符号
    printf  关键字
    (       标识符
    "Hello, World! \n"  常亮字符串值
    )       标识符
    ;   符号
*/

//输入输出
/*
putchar函数是字符输出函数，其功能是在终端（显示器）输出单个字符。
getchar函数的功能是接收用户从键盘上输入的一个字符。
printf函数叫做格式输出函数，其功能是按照用户指定的格式，把指定的数据输出到屏幕上.printf函数的格式为: printf(“格式控制字符串”,输出表项);
    d , i	以十进制形式输出有符号整数(正数不输出符号)
    O	    以八进制形式输出无符号整数(不输出前缀0)
    x	    以十六进制形式输出无符号整数(不输出前缀0x)
    U	    以十进制形式输出无符号整数
    f	    以小数形式输出单、双精度类型实数
    e	    以指数形式输出单、双精度实数
    g	    以%f或%e中较短输出宽度的一种格式输出单、双精度实数
    C	    输出单个字符
    S	    输出字符串
    *修饰符在printf()中的用法:
        假如您不想事先指定字段宽度，而是希望由程序来制定该值，那么您可以在字段宽度部分使用*代替数字来达到目的，但是您也必须使用一个参数来告诉函数宽度的值是多少。具体的说，如果转换说明符为%*d，那么参数列表中应该包括一个*的值和一个d的值，来控制宽度和变量的值。该技术也可以和浮点值一起使用来指定精度和字段宽度。 
scanf函数称为格式输入函数，即按照格式字符串的格式，从键盘上把数据输入到指定的变量之中。
    %c	        把输入解释成一个字符
    %d	        把输入解释成一个有符号十进制整数
    %e,%f,%g,%a	把输入解释成一个浮点数(%a是C99的标准)
    %E,%F,%G,%A	把输入解释成一个浮点数(%A是C99的标准)
    %i	        把输入解释成一个有符号十进制整数
    %o	        把输入解释成一个有符号的八进制整数
    %p	        把输入解释成一个指针(一个地址)
    %s	        把输入解释成一个字符串：输入的内容以第一个非空白字符作为开始，并且包含直到下一个空白字符的全部字符
    %u	        把输入解释成一个无符号十进制整数
    %x,%X	    把输入解释称一个有符号十六进制整数
    *修饰符在scanf中()的用法：
        *在scanf()中提供截然不同的服务，当把它放在%和说明符字母之间时，它使函数跳过相应的输入项目。
*/

//关键字
/*
关键字
下表列出了 C 中的保留字。这些保留字不能作为常量名、变量名或其他标识符名称。

    关键字	        说明
    auto	        声明自动变量
    break	        跳出当前循环
    case	        开关语句分支
    char	        声明字符型变量或函数返回值类型
    const	        声明只读变量
    continue	    结束当前循环，开始下一轮循环
    default	        开关语句中的"其它"分支
    do	            循环语句的循环体
    double	        声明双精度浮点型变量或函数返回值类型
    else	        条件语句否定分支（与 if 连用）
    enum	        声明枚举类型
    extern	        声明变量或函数是在其它文件或本文件的其他位置定义
    float	        声明浮点型变量或函数返回值类型
    for	            一种循环语句
    goto	        无条件跳转语句
    if	            条件语句
    int	            声明整型变量或函数
    long	        声明长整型变量或函数返回值类型
    register	    声明寄存器变量
    return	        子程序返回语句（可以带参数，也可不带参数）
    short	        声明短整型变量或函数
    signed	        声明有符号类型变量或函数
    sizeof	        计算数据类型或变量长度（即所占字节数）
    static	        声明静态变量
    struct	        声明结构体类型
    switch	        用于开关语句
    typedef	        用以给数据类型取别名
    unsigned	    声明无符号类型变量或函数
    union	        声明共用体类型
    void	        声明函数无返回值或无参数，声明无类型指针
    volatile	    说明变量在程序执行中可被隐含地改变
    while	        循环语句的循环条件

    C99 新增关键字
    _Bool	_Complex	_Imaginary	inline	restrict

    C11 新增关键字
    _Alignas	_Alignof	_Atomic	_Generic	_Noreturn
    _Static_assert	_Thread_local
*/
//在C语言中空格相关的会自动忽略

//数据类型
/*
    c语言的数据类型
        1	基本类型：
        它们是算术类型，包括两种类型：整数类型和浮点类型。
            整数类型
                char	        1 字节	        -128 到 127 或 0 到 255
                unsigned char	1 字节	        0 到 255
                signed char	    1 字节	        -128 到 127
                int	            2 或 4 字节	    -32,768 到 32,767 或 -2,147,483,648 到 2,147,483,647
                unsigned int	2 或 4 字节	    0 到 65,535 或 0 到 4,294,967,295
                short	        2 字节	        -32,768 到 32,767
                unsigned short	2 字节      	0 到 65,535
                long	        4 字节	        -2,147,483,648 到 2,147,483,647
                unsigned long	4 字节	        0 到 4,294,967,295
            浮点类型
                float	        4 字节	        1.2E-38 到 3.4E+38	        6 位小数
                double	        8 字节	        2.3E-308 到 1.7E+308	    15 位小数
                long double	    16 字节	        3.4E-4932 到 1.1E+4932	    19 位小数
        2	枚举类型：
        它们也是算术类型，被用来定义在程序中只能赋予其一定的离散整数值的变量。
        3	void 类型：
        类型说明符 void 表明没有可用的值。
            1	函数返回为空
            C 中有各种函数都不返回值，或者您可以说它们返回空。不返回值的函数的返回类型为空。例如 void exit (int status);
            2	函数参数为空
            C 中有各种函数不接受任何参数。不带参数的函数可以接受一个 void。例如 int rand(void);
            3	指针指向 void
            类型为 void * 的指针代表对象的地址，而不是类型。例如，内存分配函数 void *malloc( size_t size ); 返回指向 void 的指针，可以转换为任何数据类型。
        4	派生类型：
        它们包括：指针类型、数组类型、结构类型、共用体类型和函数类型。
*/

//变量
/*
    变量的名称可以由字母、数字和下划线字符组成。它必须以字母或下划线开头

    变量类型
        char	通常是一个字节（八位）。这是一个整数类型。
        int	    对机器而言，整数的最自然的大小。
        float	单精度浮点值。单精度是这样的格式，1位符号，8位指数，23位小数。
        double	双精度浮点值。双精度是1位符号，11位指数，52位小数。
        void	表示类型的缺失。
        C 语言也允许定义各种其他类型的变量，比如枚举、指针、数组、结构、共用体等等
    c语言变量定义
        类型    变量名称 = 初始值（可不加）
    例：
        int     i, j, k = 5;
        char    c, ch = 5;
        float   f, salary = 5.0;
        double  d = 1; 
    C 中的左值（Lvalues）和右值（Rvalues）
    C 中有两种类型的表达式：
        左值（lvalue）：指向内存位置的表达式被称为左值（lvalue）表达式。左值可以出现在赋值号的左边或右边。
        右值（rvalue）：术语右值（rvalue）指的是存储在内存中某些地址的数值。右值是不能对其进行赋值的表达式，也就是说，右值可以出现在赋值号的右边，但不能出现在赋值号的左边。
    变量是左值，因此可以出现在赋值号的左边。数值型的字面值是右值，因此不能被赋值，不能出现在赋值号的左边。 
    int g = 20; 正确
    10 = 20; 错误      
*/

//c常量
/*
    整数常量    整数常量可以是十进制、八进制或十六进制的常量
    前缀指定基数：0x 或 0X 表示十六进制，0 表示八进制，不带前缀则默认表示十进制。
    整数常量也可以带一个后缀，后缀是 U 和 L 的组合，U 表示无符号整数（unsigned），L 表示长整数（long）。后缀可以是大写，也可以是小写，U 和 L 的顺序任意。
        212    合法的
        215u   合法的
        0xFeeL 合法的 
        078    非法的：8 不是八进制的数字
        032UU  非法的：不能重复后缀
        85     十进制 
        0213   八进制 
        0x4b   十六进制 
        30     整数 
        30u    无符号整数
        30l    长整数
        30ul   无符号长整数

    浮点常量    浮点常量由整数部分、小数点、小数部分和指数部分组成。您可以使用小数形式或者指数形式来表示浮点常量。
    当使用小数形式表示时，必须包含整数部分、小数部分，或同时包含两者。当使用指数形式表示时， 必须包含小数点、指数，或同时包含两者。带符号的指数是用 e 或 E 引入的。
        3.14159     合法的 
        314159E-5L  合法的 
        510E        非法的：不完整的指数 
        210f        非法的：没有小数或指数 
        .e55        非法的：缺少整数或分数 

    字符常量    字符常量是括在单引号中，例如，'x' 可以存储在 char 类型的简单变量中。
    字符常量可以是一个普通的字符（例如 'x'）、一个转义序列（例如 '\t'），或一个通用的字符（例如 '\u02C0'）。
    在 C 中，有一些特定的字符，当它们前面有反斜杠时，它们就具有特殊的含义，被用来表示如换行符（\n）或制表符（\t）等。 
        转义字符        含义
        \\	            \ 字符
        \'	            ' 字符
        \"	            " 字符
        \?	            ? 字符
        \a	            警报铃声
        \b	            退格键
        \f	            换页符
        \n	            换行符
        \r	            回车
        \t	            水平制表符
        \v	            垂直制表符
        \ooo            一到三位的八进制数
        \xhh . . .	    一个或多个数字的十六进制数   

    定义常量    #define 预处理器    const 关键字
        #define 预处理器    #define identifier value    
        const 关键字        const type variable = value;
*/

//c语言储存类
/*
    C 存储类
    存储类定义 C 程序中变量/函数的范围（可见性）和生命周期。这些说明符放置在它们所修饰的类型之前。下面列出 C 程序中可用的存储类：
        auto 存储类      auto 存储类是所有局部变量默认的存储类。
        register        存储类 register 存储类用于定义存储在寄存器中而不是 RAM 中的局部变量。这意味着变量的最大尺寸等于寄存器的大小（通常是一个词），且不能对它应用一元的 '&' 运算符（因为它没有内存位置）。
        static 存储类    static 存储类指示编译器在程序的生命周期内保持局部变量的存在，而不需要在每次它进入和离开作用域时进行创建和销毁。因此，使用 static 修饰局部变量可以在函数调用之间保持局部变量的值。static 修饰符也可以应用于全局变量。当 static 修饰全局变量时，会使变量的作用域限制在声明它的文件内。全局声明的一个 static 变量或方法可以被任何函数或方法调用，只要这些方法出现在跟 static 变量或方法同一个文件中。
        extern 存储类   用于提供一个全局变量的引用，全局变量对所有的程序文件都是可见的。当您使用 'extern' 时，对于无法初始化的变量，会把变量名指向一个之前定义过的存储位置。当您有多个文件且定义了一个可以在其他文件中使用的全局变量或函数时，可以在其他文件中使用 extern 来得到已定义的变量或函数的引用。可以这么理解，extern 是用来在另一个文件中声明一个全局变量或函数。extern 修饰符通常用于当有两个或多个文件共享相同的全局变量或函数的时候
*/

//c运算符
/*
    C 运算符    运算符是一种告诉编译器执行特定的数学或逻辑操作的符号。C 语言内置了丰富的运算符，并提供了以下类型的运算符：
        算术运算符
        关系运算符
        逻辑运算符
        位运算符
        赋值运算符
        杂项运算符
    算术运算符
        +	把两个操作数相加	                   A + B 将得到 30
        -	从第一个操作数中减去第二个操作数	    A - B 将得到 -10
        *	把两个操作数相乘	                  A * B 将得到 200
        /	分子除以分母	                     B / A 将得到 2
        %	取模运算符，整除后的余数	          B % A 将得到 0
        ++	自增运算符，整数值增加 1	          A++ 将得到 11
        --	自减运算符，整数值减少 1	          A-- 将得到 9    
    关系运算符
        ==	检查两个操作数的值是否相等，如果相等则条件为真。	            (A == B) 不为真。
        !=	检查两个操作数的值是否相等，如果不相等则条件为真。	            (A != B) 为真。
        >	检查左操作数的值是否大于右操作数的值，如果是则条件为真。	    (A > B) 不为真。
        <	检查左操作数的值是否小于右操作数的值，如果是则条件为真。	    (A < B) 为真。
        >=	检查左操作数的值是否大于或等于右操作数的值，如果是则条件为真。	(A >= B) 不为真。
        <=	检查左操作数的值是否小于或等于右操作数的值，如果是则条件为真。	(A <= B) 为真。
    逻辑运算符
        &&	称为逻辑与运算符。如果两个操作数都非零，则条件为真。	                          (A && B) 为假。
        ||	称为逻辑或运算符。如果两个操作数中有任意一个非零，则条件为真。	                   (A || B) 为真。
        !	称为逻辑非运算符。用来逆转操作数的逻辑状态。如果条件为真则逻辑非运算符将使其为假。	!(A && B) 为真。 
    位运算符
        待学习完善

    赋值运算符
        =	简单的赋值运算符，把右边操作数的值赋给左边操作数	                C = A + B 将把 A + B 的值赋给 C
        +=	加且赋值运算符，把右边操作数加上左边操作数的结果赋值给左边操作数	 C += A 相当于 C = C + A
        -=	减且赋值运算符，把左边操作数减去右边操作数的结果赋值给左边操作数	 C -= A 相当于 C = C - A
        *=	乘且赋值运算符，把右边操作数乘以左边操作数的结果赋值给左边操作数	 C *= A 相当于 C = C * A
        /=	除且赋值运算符，把左边操作数除以右边操作数的结果赋值给左边操作数	 C /= A 相当于 C = C / A
        %=	求模且赋值运算符，求两个操作数的模赋值给左边操作数	                C %= A 相当于 C = C % A
        <<=	左移且赋值运算符	                                             C <<= 2 等同于 C = C << 2
        >>=	右移且赋值运算符	                                             C >>= 2 等同于 C = C >> 2
        &=	按位与且赋值运算符	                                             C &= 2 等同于 C = C & 2
        ^=	按位异或且赋值运算符	                                         C ^= 2 等同于 C = C ^ 2
        |=	按位或且赋值运算符	                                             C |= 2 等同于 C = C | 2   
    杂项运算符
        sizeof()	返回变量的大小。	sizeof(a) 将返回 4，其中 a 是整数。
        &	        返回变量的地址。	&a; 将给出变量的实际地址。
        *	        指向一个变量。	    *a; 将指向一个变量。
        ? :	        条件表达式	        如果条件为真 ? 则值为 X : 否则值为 Y
    运算符优先级
        后缀 	() [] -> . ++ - -  	                从左到右 
        一元 	+ - ! ~ ++ - - (type)* & sizeof 	从右到左 
        乘除 	* / % 	                            从左到右 
        加减 	+ - 	                            从左到右 
        移位 	<< >> 	                            从左到右 
        关系 	< <= > >= 	                        从左到右 
        相等 	== != 	                            从左到右 
        位与 AND 	& 	                            从左到右 
        位异或 XOR 	^ 	                            从左到右 
        位或 OR 	| 	                            从左到右 
        逻辑与 AND 	&& 	                            从左到右 
        逻辑或 OR 	|| 	                            从左到右 
        条件 	?: 	                                从右到左 
        赋值 	= += -= *= /= %=>>= <<= &= ^= |= 	从右到左 
        逗号 	, 	                                从左到右 
*/

//c 判断
/*
判断结构要求程序员指定一个或多个要评估或测试的条件，以及条件为真时要执行的语句（必需的）和条件为假时要执行的语句（可选的）。
C 语言把任何非零和非空的值假定为 true，把零或 null 假定为 false。

判断语句
    语句	            描述
    if 语句	            一个 if 语句 由一个布尔表达式后跟一个或多个语句组成。
    if...else 语句	    一个 if 语句 后可跟一个可选的 else 语句，else 语句在布尔表达式为假时执行。
    嵌套 if 语句	    您可以在一个 if 或 else if 语句内使用另一个 if 或 else if 语句。
    switch 语句	        一个 switch 语句允许测试一个变量等于多个值时的情况。
    嵌套 switch 语句	您可以在一个 switch 语句内使用另一个 switch 语句。
? : 运算符(三元运算符)  Exp1 ? Exp2 : Exp3;
*/

//循环
/*
有的时候，我们可能需要多次执行同一块代码。一般情况下，语句是按顺序执行的：函数中的第一个语句先执行，接着是第二个语句，依此类推。

循环类型
    循环类型	        描述
    while 循环	        当给定条件为真时，重复语句或语句组。它会在执行循环主体之前测试条件。
    for 循环	        多次执行一个语句序列，简化管理循环变量的代码。
    do...while          循环	除了它是在循环主体结尾测试条件外，其他与 while 语句类似。
    嵌套循环	        您可以在 while、for 或 do..while 循环内使用一个或多个循环。
循环控制语句
    控制语句	        描述
    break 语句	        终止循环或 switch 语句，程序流将继续执行紧接着循环或 switch 的下一条语句。
    continue 语句	    告诉一个循环体立刻停止本次循环迭代，重新开始下次循环迭代。
    goto 语句	        将控制转移到被标记的语句。但是不建议在程序中使用 goto 语句。
*/

 //c 函数
/*
函数是一组一起执行一个任务的语句。每个 C 程序都至少有一个函数，即主函数 main() ，所有简单的程序都可以定义其他额外的函数。
您可以把代码划分到不同的函数中。如何划分代码到不同的函数中是由您来决定的，但在逻辑上，划分通常是根据每个函数执行一个特定的任务来进行的。
函数声明告诉编译器函数的名称、返回类型和参数。函数定义提供了函数的实际主体。
C 标准库提供了大量的程序可以调用的内置函数。例如，函数 strcat() 用来连接两个字符串，函数 memcpy() 用来复制内存到另一个位置。

定义函数
    return_type function_name( parameter list )
    {
        body of the function
    }

函数由一个函数头和一个函数主体组成。下面列出一个函数的所有组成部分：
    返回类型：一个函数可以返回一个值。return_type 是函数返回的值的数据类型。有些函数执行所需的操作而不返回值，在这种情况下，return_type 是关键字 void。
    函数名称：这是函数的实际名称。函数名和参数列表一起构成了函数签名。
    参数：参数就像是占位符。当函数被调用时，您向参数传递一个值，这个值被称为实际参数。参数列表包括函数参数的类型、顺序、数量。参数是可选的，也就是说，函数可能不包含参数。
    函数主体：函数主体包含一组定义函数执行任务的语句。

函数声明    函数声明会告诉编译器函数名称及如何调用函数。函数的实际主体可以单独定义。
    return_type function_name( parameter list );

调用函数
    创建 C 函数时，会定义函数做什么，然后通过调用函数来完成已定义的任务。
    当程序调用函数时，程序控制权会转移给被调用的函数。被调用的函数执行已定义的任务，当函数的返回语句被执行时，或到达函数的结束括号时，会把程序控制权交还给主程序。

函数参数
    如果函数要使用参数，则必须声明接受参数值的变量。这些变量称为函数的形式参数。
    形式参数就像函数内的其他局部变量，在进入函数时被创建，退出函数时被销毁。
 */

// 作用域
/*
任何一种编程中，作用域是程序中定义的变量所存在的区域，超过该区域变量就不能被访问。C 语言中有三个地方可以声明变量：
    在函数或块内部的局部变量
    在所有函数外部的全局变量
    在形式参数的函数参数定义中
什么是局部变量、全局变量和形式参数:
    局部变量 ： 在某个函数或块的内部声明的变量称为局部变量。它们只能被该函数或该代码块内部的语句使用。
        #include <stdio.h> 
            int main ()
            {

                int a, b;
                int c;


                a = 10;
                b = 20;
                c = a + b;

                printf("value of a = %d, b = %d and c = %d\n", a, b, c);

                return 0;
            }
    全局变量 ：全局变量是定义在函数外部，通常是在程序的顶部。全局变量在整个程序生命周期内都是有效的，在任意的函数内部能访问全局变量。全局变量可以被任何函数访问。
        #include <stdio.h>
 
        int g;  //全局变量

        int main()
        {
            int a, b;

            a = 10;
            b = 20;
            g = a + b;

            printf("value of a = %d, b = %d and g = %d\n", a, b, g);

            return 0;
        }
    注意 ： 在程序中，局部变量和全局变量的名称可以相同，但是在函数内，局部变量的值会覆盖全局变量的值。
        #include <stdio.h>
 
        int g = 20;

        int main()
        {
            int g = 10;

            printf("value of g = %d\n", g);

            return 0;
        }
        结果    value of g = 10
    形式参数 ： 函数的参数，形式参数，被当作该函数内的局部变量，它们会优先覆盖全局变量。
        #include <stdio.h>
 
        int a = 20;

        int main()
        {

            int a = 10;
            int b = 20;
            int c = 0;
            int sum(int, int);

            printf("value of a in main() = %d\n", a);
            c = sum(a, b);
            printf("value of c in main() = %d\n", c);

            return 0;
        }

        int sum(int a, int b)
        {
            printf("value of a in sum() = %d\n", a);
            printf("value of b in sum() = %d\n", b);

            return a + b;
        }
    结果    value of a in main() = 10
            value of a in sum() = 10
            value of b in sum() = 20
            value of c in main() = 30
    初始化局部变量和全局变量
    当局部变量被定义时，系统不会对其初始化，您必须自行对其初始化。定义全局变量时，系统会自动对其初始化，如下所示：

    数据类型	初始化默认值
    int	        0
    char	    '\0'
    float	    0
    double	    0
    pointer	    NULL
    正确地初始化变量是一个良好的编程习惯，否则有时候程序可能会产生意想不到的结果，因为未初始化的变量会导致一些在内存位置中已经可用的垃圾值。
    形参与实参 ： 形参与实参虽然很简单，但是，是大家比较容易混淆的一个点，这里将为大家详细的讲解。
    概念：从字面上理解，所谓形式参数即只只是声明了一个作为参数的变量，并未直接进行赋值使用，而实际参数则相反。
        #include <stdio.h>

        int test(int,int); // 形参，只声明

        int main()
        {
            int a,b;
            printf("%d",test(5,3)); // 实参，已赋值
        }

        int test(int a,int b) // 形参
        {
            a=a+b;
            return a;
        }
*/

// c语言数组
/*
    C 语言支持数组数据结构，它可以存储一个固定大小的相同类型元素的顺序集合。数组是用来存储一系列数据，但它往往被认为是一系列相同类型的变量。
    数组的声明并不是声明一个个单独的变量，比如 number0、number1、...、number99，而是声明一个数组变量，比如 numbers，然后使用 numbers[0]、numbers[1]、...、numbers[99] 来代表一个个单独的变量。数组中的特定元素可以通过索引访问。所有的数组都是由连续的内存位置组成。最低的地址对应第一个元素，最高的地址对应最后一个元素。
    声明数组 : 在 C 中要声明一个数组，需要指定元素的类型和元素的数量
        type arrayName[arraysize];
        这叫做一维数组。arraySize 必须是一个大于零的整数常量，type 可以是任意有效的 C 数据类型。
    初始化数组 : 在 C 中，您可以逐个初始化数组，也可以使用一个初始化语句
        double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};
        大括号 { } 之间的值的数目不能大于我们在数组声明时在方括号 [ ] 中指定的元素数目。如果您省略掉了数组的大小，数组的大小则为初始化时元素的个数。
        double balance[] = {1000.0, 2.0, 3.4, 7.0, 50.0}; //与上面数组相同
        balance[4] = 50.0; //把数组中第五个元素的值赋为 50.0。所有的数组都是以 0 作为它们第一个元素的索引，也被称为基索引，数组的最后一个索引是数组的总大小减去 1
        访问数组元素 ：数组元素可以通过数组名称加索引进行访问。元素的索引是放在方括号内，跟在数组名称的后边。
        double salary = balance[9];
            #include <stdio.h>
 
            int main ()
            {
            int n[ 10 ]; 
            int i, j;

            
            for (i = 0; i < 10; i++)
            {
                n[i] = i + 100; 
            }

            
            for (j = 0; j < 10; j++)
            {
                printf("Element[%d] = %d\n", j, n[j]);
            }

            return 0;
            }
    结果 ：  Element[0] = 100
            Element[1] = 101
            Element[2] = 102
            Element[3] = 103
            Element[4] = 104
            Element[5] = 105
            Element[6] = 106
            Element[7] = 107
            Element[8] = 108
            Element[9] = 109
    C 中数组详解 ：在 C 中，数组是非常重要的，我们需要了解更多有关数组的细节。下面列出了 C 程序员必须清楚的一些与数组相关的重要概念：
        概念	描述
        多维数组	C 支持多维数组。多维数组最简单的形式是二维数组。
        传递数组给函数	您可以通过指定不带索引的数组名称来给函数传递一个指向数组的指针。
        从函数返回数组	C 允许从函数返回数组。
        指向数组的指针	您可以通过指定不带索引的数组名称来生成一个指向数组中第一个元素的指针。
*/

// 枚举

/*
    C enum(枚举) 枚举是 C 语言中的一种基本数据类型，它可以让数据更简洁，更易读。
    enum　枚举名　{枚举元素1,枚举元素2,……};
    enum DAY
    {
        MON=1, TUE, WED, THU, FRI, SAT, SUN
    };
    注意：第一个枚举成员的默认值为整型的 0，后续枚举成员的值在前一个成员上加 1。我们在这个实例中把第一个枚举成员的值定义为 1，第二个就为 2，以此类推。
    可以在定义枚举类型时改变枚举元素的值：
        enum season {spring, summer=3, autumn, winter};
    没有指定值的枚举元素，其值为前一元素加 1。也就说 spring 的值为 0，summer 的值为 3，autumn 的值为 4，winter 的值为 5

    枚举变量的定义
    前面我们只是声明了枚举类型，接下来我们看看如何定义枚举变量。

    我们可以通过以下三种方式来定义枚举变量

    1、先定义枚举类型，再定义枚举变量

    enum DAY
    {
        MON=1, TUE, WED, THU, FRI, SAT, SUN
    };
    enum DAY day;
    2、定义枚举类型的同时定义枚举变量

    enum DAY
    {
        MON=1, TUE, WED, THU, FRI, SAT, SUN
    } day;
    3、省略枚举名称，直接定义枚举变量

    enum
    {
        MON=1, TUE, WED, THU, FRI, SAT, SUN
    } day;
    实例
    #include<stdio.h>
    
    enum DAY
    {
        MON=1, TUE, WED, THU, FRI, SAT, SUN
    };
    
    int main()
    {
        enum DAY day;
        day = WED;
        printf("%d",day);
        return 0;
    }
    结果 ： 3
    在C 语言中，枚举类型是被当做 int 或者 unsigned int 类型来处理的，所以按照 C 语言规范是没有办法遍历枚举类型的。
    枚举类型转换weekend = （enum day）a;    (但是weekend = a 也可以)
    
*/